package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.tanhua.autoconfig.template.HuanXinTemplate;
import com.tanhua.dubbo.api.*;
import com.tanhua.model.domain.Question;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.dto.RecommendUserDto;
import com.tanhua.model.mongo.RecommendUser;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.NearUserVo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.TodayBest;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import com.tanhua.utils.Constants;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class TanhuaService {
    @DubboReference
    private RecommendUserApi recommendUserApi;
    @DubboReference
    private UserInfoApi userInfoApi;
    @DubboReference
    private QuestionApi questionApi;
    @Autowired
    private HuanXinTemplate huanXinTemplate;
    @Value("${tanhua.default.recommend.users}")
    private String recommendUser;
   @DubboReference
   private UserLikeApi userLikeApi;
   @Autowired
   private RedisTemplate<String ,String> redisTemplate;
   @Autowired
   private  MessagesService messagesService;
   @DubboReference
   private UserLocationApi userLocationApi;
   @DubboReference
   private VisitorsApi visitorsApi;


    public TodayBest todayBest() {

        Long userId = UserHolder.getUserId();
        RecommendUser recommendUser = recommendUserApi.queryWithMaxScore(userId);
        if (recommendUser==null){
            RecommendUser recommendUsers = new RecommendUser();
            recommendUsers.setUserId(1L);
            recommendUsers.setScore(99d);
        }
        UserInfo userInfo = new UserInfo();
        TodayBest recommendUservo = new TodayBest();
        if (recommendUser!=null){
             userInfo = userInfoApi.findById(recommendUser.getUserId());
             recommendUservo = TodayBest.init(userInfo, recommendUser);
        }
        return recommendUservo;
    }

    public PageResult recommendation(RecommendUserDto dto) {
        Long userId = UserHolder.getUserId();
        PageResult pr = recommendUserApi.queryRecommendUserList(dto.getPage(),dto.getPagesize(),userId);
        List<RecommendUser> items = (List<RecommendUser>) pr.getItems();
        if (items==null||items.size()<=0){
            return pr;
        }
        List<Long> userids = CollUtil.getFieldValues(items, "userId", Long.class);
        UserInfo userInfo = new UserInfo();
        userInfo.setAge(dto.getAge());
        userInfo.setGender(dto.getGender());
        Map<Long,UserInfo> map = userInfoApi.findbyIds(userids,null);
        List<TodayBest>  list= new ArrayList();
        for (RecommendUser item : items) {
            UserInfo info = map.get(item.getUserId());
            if (info!=null){
                TodayBest todayBest = TodayBest.init(info, item);
                list.add(todayBest);
            }
        }
        pr.setItems(list);
        return pr;
    }

    public TodayBest personalInfo(Long userid) {
        UserInfo userInfo = userInfoApi.findById(userid);
       RecommendUser recommendUser = recommendUserApi.byuserid(userid,UserHolder.getUserId());
        Visitors visitors = new Visitors();
        visitors.setUserId(userid);
        visitors.setVisitorUserId(UserHolder.getUserId());
        visitors.setFrom("首页");
        visitors.setDate(System.currentTimeMillis());
        visitors.setVisitDate(new SimpleDateFormat("yyyyMMdd").format(new Date()));
        visitors.setScore(recommendUser.getScore());
        visitorsApi.save(visitors);
        return TodayBest.init(userInfo,recommendUser);
    }

    public String strangerQuestions(Long userId) {
        Question question = questionApi.findByUserId(userId);
      return question == null ? "你喜欢java吗?" : question.getTxt();
    }

    public void replyQuestions(Long userId, String reply) {
        // {"userId":106,"huanXinId":"hx106","nickname":"黑马小妹","strangerQuestion":"你喜欢去看蔚蓝的大海还是去爬巍峨的高山？",
        // "reply":"我喜欢秋天的落叶，夏天的泉水，冬天的雪地，只要有你一切皆可~"}
        Long id = UserHolder.getUserId();
        UserInfo userInfo = userInfoApi.findById(id);
        Map map = new HashMap();
        map.put("userId",id);
        map.put("huanXinId", Constants.HX_USER_PREFIX+id);
        map.put("nickname",userInfo.getNickname());
        map.put("strangerQuestion",strangerQuestions(userId));
        map.put("reply",reply);
        String jsonString = JSON.toJSONString(map);

        Boolean aBoolean = huanXinTemplate.sendMsg(Constants.HX_USER_PREFIX + id, jsonString);
        if (!aBoolean){
            throw new BusinessException(ErrorResult.error());
        }

    }

    public List<TodayBest> queryCardsList() {
        Long userId = UserHolder.getUserId();
         List<RecommendUser> list =recommendUserApi.cardsList(userId,10);
         if (CollUtil.isEmpty(list)){
             list = new ArrayList<>();
             String[] ids = recommendUser.split(",");
             for (String id : ids) {
                 RecommendUser recommendUser = new RecommendUser();
                 recommendUser.setUserId(Long.valueOf(id));
                 recommendUser.setToUserId(userId);
                 recommendUser.setScore(RandomUtil.randomDouble(80,90));
                 list.add(recommendUser);
             }
         }
        List<Long> userIds = CollUtil.getFieldValues(list, "userId", Long.class);
        Map<Long, UserInfo> map = userInfoApi.findbyIds(userIds, null);

        List<TodayBest> bestList = new ArrayList<>();
        for (RecommendUser user : list) {
            UserInfo userInfo = map.get(user.getUserId());
            if (userInfo!=null){
                TodayBest todayBest = TodayBest.init(userInfo, user);
                bestList.add(todayBest);
            }
        }
        return bestList;
    }

    public void likeuser(Long userid,boolean flag) {
        Boolean saveOrUpdate = userLikeApi.saveOrUpdate(UserHolder.getUserId(), userid, flag);
        Boolean member = redisTemplate.opsForSet().isMember(Constants.USER_LIKE_KEY + userid, UserHolder.getUserId().toString());
        if (flag){
            if (!saveOrUpdate){
                throw new BusinessException(ErrorResult.error());
            }
            redisTemplate.opsForSet().remove(Constants.USER_NOT_LIKE_KEY+UserHolder.getUserId(),userid.toString());
            redisTemplate.opsForSet().add(Constants.USER_LIKE_KEY+UserHolder.getUserId(),userid.toString());
            if (member){
                messagesService.contacts(UserHolder.getUserId());
            }
        }else {
            if (!saveOrUpdate){
                throw new BusinessException(ErrorResult.error());
            }
            redisTemplate.opsForSet().remove(Constants.USER_LIKE_KEY+UserHolder.getUserId(),userid.toString());
            redisTemplate.opsForSet().add(Constants.USER_NOT_LIKE_KEY+UserHolder.getUserId(),userid.toString());
            Boolean memberd = redisTemplate.opsForSet().isMember(Constants.USER_NOT_LIKE_KEY + UserHolder.getUserId(), userid.toString());
            if (memberd){
                messagesService.deleteContact(userid);
            }
        }
    }

    public List<NearUserVo> nearuser(String gender, String distance) {
        List<Long> userIds = userLocationApi.queryNearUser(UserHolder.getUserId(),Double.valueOf(distance));
        if (CollUtil.isEmpty(userIds)){
            return new ArrayList<>();
        }
        UserInfo userInfo = new UserInfo();
        userInfo.setGender(gender);
        Map<Long, UserInfo> map = userInfoApi.findbyIds(userIds, userInfo);
        List<NearUserVo> list = new ArrayList<>();
        for (Long userId : userIds) {
            if (userId==UserHolder.getUserId()){
                continue;
            }
            UserInfo info = map.get(userId);
            if (info!=null){
                NearUserVo nearUserVo = NearUserVo.init(info);
                list.add(nearUserVo);
            }
        }
        return list;
    }
}
